home *** CD-ROM | disk | FTP | other *** search
/ EuroCD 3 / EuroCD 3.iso / Games / Doom / ADoom-0.8 / ADoom_src / st_stuff.c < prev    next >
C/C++ Source or Header  |  1998-06-24  |  30KB  |  1,472 lines

  1. // Emacs style mode select   -*- C++ -*- 
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. // $Log:$
  18. //
  19. // DESCRIPTION:
  20. //    Status bar code.
  21. //    Does the face/direction indicator animatin.
  22. //    Does palette indicators as well (red pain/berserk, bright pickup)
  23. //
  24. //-----------------------------------------------------------------------------
  25.  
  26. static const char
  27. rcsid[] = "$Id: st_stuff.c,v 1.6 1997/02/03 22:45:13 b1 Exp $";
  28.  
  29.  
  30. #include <stdio.h>
  31.  
  32. #include "i_system.h"
  33. #include "i_video.h"
  34. #include "z_zone.h"
  35. #include "m_random.h"
  36. #include "w_wad.h"
  37.  
  38. #include "doomdef.h"
  39.  
  40. #include "g_game.h"
  41.  
  42. #include "st_stuff.h"
  43. #include "st_lib.h"
  44. #include "r_local.h"
  45.  
  46. #include "p_local.h"
  47. #include "p_inter.h"
  48.  
  49. #include "am_map.h"
  50. #include "m_cheat.h"
  51.  
  52. #include "s_sound.h"
  53.  
  54. // Needs access to LFB.
  55. #include "v_video.h"
  56.  
  57. // State.
  58. #include "doomstat.h"
  59.  
  60. // Data.
  61. #include "dstrings.h"
  62. #include "sounds.h"
  63.  
  64. //
  65. // STATUS BAR DATA
  66. //
  67.  
  68.  
  69. // Palette indices.
  70. // For damage/bonus red-/gold-shifts
  71. #define STARTREDPALS        1
  72. #define STARTBONUSPALS        9
  73. #define NUMREDPALS            8
  74. #define NUMBONUSPALS        4
  75. // Radiation suit, green shift.
  76. #define RADIATIONPAL        13
  77.  
  78. // N/256*100% probability
  79. //  that the normal face state will change
  80. #define ST_FACEPROBABILITY        96
  81.  
  82. // For Responder
  83. #define ST_TOGGLECHAT        KEY_ENTER
  84.  
  85. // Location of status bar
  86. #define ST_X                0
  87. #define ST_X2                104
  88.  
  89. #define ST_FX              143
  90. #define ST_FY              169
  91.  
  92. // Should be set to patch width
  93. //  for tall numbers later on
  94. #define ST_TALLNUMWIDTH        (tallnum[0]->width)
  95.  
  96. // Number of status faces.
  97. #define ST_NUMPAINFACES        5
  98. #define ST_NUMSTRAIGHTFACES    3
  99. #define ST_NUMTURNFACES        2
  100. #define ST_NUMSPECIALFACES        3
  101.  
  102. #define ST_FACESTRIDE \
  103.           (ST_NUMSTRAIGHTFACES+ST_NUMTURNFACES+ST_NUMSPECIALFACES)
  104.  
  105. #define ST_NUMEXTRAFACES        2
  106.  
  107. #define ST_NUMFACES \
  108.           (ST_FACESTRIDE*ST_NUMPAINFACES+ST_NUMEXTRAFACES)
  109.  
  110. #define ST_TURNOFFSET        (ST_NUMSTRAIGHTFACES)
  111. #define ST_OUCHOFFSET        (ST_TURNOFFSET + ST_NUMTURNFACES)
  112. #define ST_EVILGRINOFFSET        (ST_OUCHOFFSET + 1)
  113. #define ST_RAMPAGEOFFSET        (ST_EVILGRINOFFSET + 1)
  114. #define ST_GODFACE            (ST_NUMPAINFACES*ST_FACESTRIDE)
  115. #define ST_DEADFACE            (ST_GODFACE+1)
  116.  
  117. #define ST_FACESX            143
  118. #define ST_FACESY            168
  119.  
  120. #define ST_EVILGRINCOUNT        (2*TICRATE)
  121. #define ST_STRAIGHTFACECOUNT    (TICRATE/2)
  122. #define ST_TURNCOUNT        (1*TICRATE)
  123. #define ST_OUCHCOUNT        (1*TICRATE)
  124. #define ST_RAMPAGEDELAY        (2*TICRATE)
  125.  
  126. #define ST_MUCHPAIN            20
  127.  
  128.  
  129. // Location and size of statistics,
  130. //  justified according to widget type.
  131. // Problem is, within which space? STbar? Screen?
  132. // Note: this could be read in by a lump.
  133. //       Problem is, is the stuff rendered
  134. //       into a buffer,
  135. //       or into the frame buffer?
  136.  
  137. // AMMO number pos.
  138. #define ST_AMMOWIDTH        3    
  139. #define ST_AMMOX            44
  140. #define ST_AMMOY            171
  141.  
  142. // HEALTH number pos.
  143. #define ST_HEALTHWIDTH        3    
  144. #define ST_HEALTHX            90
  145. #define ST_HEALTHY            171
  146.  
  147. // Weapon pos.
  148. #define ST_ARMSX            111
  149. #define ST_ARMSY            172
  150. #define ST_ARMSBGX            104
  151. #define ST_ARMSBGY            168
  152. #define ST_ARMSXSPACE        12
  153. #define ST_ARMSYSPACE        10
  154.  
  155. // Frags pos.
  156. #define ST_FRAGSX            138
  157. #define ST_FRAGSY            171    
  158. #define ST_FRAGSWIDTH        2
  159.  
  160. // ARMOR number pos.
  161. #define ST_ARMORWIDTH        3
  162. #define ST_ARMORX            221
  163. #define ST_ARMORY            171
  164.  
  165. // Key icon positions.
  166. #define ST_KEY0WIDTH        8
  167. #define ST_KEY0HEIGHT        5
  168. #define ST_KEY0X            239
  169. #define ST_KEY0Y            171
  170. #define ST_KEY1WIDTH        ST_KEY0WIDTH
  171. #define ST_KEY1X            239
  172. #define ST_KEY1Y            181
  173. #define ST_KEY2WIDTH        ST_KEY0WIDTH
  174. #define ST_KEY2X            239
  175. #define ST_KEY2Y            191
  176.  
  177. // Ammunition counter.
  178. #define ST_AMMO0WIDTH        3
  179. #define ST_AMMO0HEIGHT        6
  180. #define ST_AMMO0X            288
  181. #define ST_AMMO0Y            173
  182. #define ST_AMMO1WIDTH        ST_AMMO0WIDTH
  183. #define ST_AMMO1X            288
  184. #define ST_AMMO1Y            179
  185. #define ST_AMMO2WIDTH        ST_AMMO0WIDTH
  186. #define ST_AMMO2X            288
  187. #define ST_AMMO2Y            191
  188. #define ST_AMMO3WIDTH        ST_AMMO0WIDTH
  189. #define ST_AMMO3X            288
  190. #define ST_AMMO3Y            185
  191.  
  192. // Indicate maximum ammunition.
  193. // Only needed because backpack exists.
  194. #define ST_MAXAMMO0WIDTH        3
  195. #define ST_MAXAMMO0HEIGHT        5
  196. #define ST_MAXAMMO0X        314
  197. #define ST_MAXAMMO0Y        173
  198. #define ST_MAXAMMO1WIDTH        ST_MAXAMMO0WIDTH
  199. #define ST_MAXAMMO1X        314
  200. #define ST_MAXAMMO1Y        179
  201. #define ST_MAXAMMO2WIDTH        ST_MAXAMMO0WIDTH
  202. #define ST_MAXAMMO2X        314
  203. #define ST_MAXAMMO2Y        191
  204. #define ST_MAXAMMO3WIDTH        ST_MAXAMMO0WIDTH
  205. #define ST_MAXAMMO3X        314
  206. #define ST_MAXAMMO3Y        185
  207.  
  208. // pistol
  209. #define ST_WEAPON0X            110 
  210. #define ST_WEAPON0Y            172
  211.  
  212. // shotgun
  213. #define ST_WEAPON1X            122 
  214. #define ST_WEAPON1Y            172
  215.  
  216. // chain gun
  217. #define ST_WEAPON2X            134 
  218. #define ST_WEAPON2Y            172
  219.  
  220. // missile launcher
  221. #define ST_WEAPON3X            110 
  222. #define ST_WEAPON3Y            181
  223.  
  224. // plasma gun
  225. #define ST_WEAPON4X            122 
  226. #define ST_WEAPON4Y            181
  227.  
  228.  // bfg
  229. #define ST_WEAPON5X            134
  230. #define ST_WEAPON5Y            181
  231.  
  232. // WPNS title
  233. #define ST_WPNSX            109 
  234. #define ST_WPNSY            191
  235.  
  236.  // DETH title
  237. #define ST_DETHX            109
  238. #define ST_DETHY            191
  239.  
  240. //Incoming messages window location
  241. //UNUSED
  242. // #define ST_MSGTEXTX       (viewwindowx)
  243. // #define ST_MSGTEXTY       (viewwindowy+viewheight-18)
  244. #define ST_MSGTEXTX            0
  245. #define ST_MSGTEXTY            0
  246. // Dimensions given in characters.
  247. #define ST_MSGWIDTH            52
  248. // Or shall I say, in lines?
  249. #define ST_MSGHEIGHT        1
  250.  
  251. #define ST_OUTTEXTX            0
  252. #define ST_OUTTEXTY            6
  253.  
  254. // Width, in characters again.
  255. #define ST_OUTWIDTH            52 
  256.  // Height, in lines. 
  257. #define ST_OUTHEIGHT        1
  258.  
  259. #define ST_MAPWIDTH    \
  260.     (strlen(mapnames[(gameepisode-1)*9+(gamemap-1)]))
  261.  
  262. #define ST_MAPTITLEX \
  263.     (SCREENWIDTH - ST_MAPWIDTH * ST_CHATFONTWIDTH)
  264.  
  265. #define ST_MAPTITLEY        0
  266. #define ST_MAPHEIGHT        1
  267.  
  268.         
  269. // main player in game
  270. static player_t*    plyr; 
  271.  
  272. // ST_Start() has just been called
  273. static boolean        st_firsttime;
  274.  
  275. // used to execute ST_Init() only once
  276. static int        veryfirsttime = 1;
  277.  
  278. // lump number for PLAYPAL
  279. static int        lu_palette;
  280.  
  281. // used for timing
  282. static unsigned int    st_clock;
  283.  
  284. // used for making messages go away
  285. static int        st_msgcounter=0;
  286.  
  287. // used when in chat 
  288. static st_chatstateenum_t    st_chatstate;
  289.  
  290. // whether in automap or first-person
  291. static st_stateenum_t    st_gamestate;
  292.  
  293. // whether left-side main status bar is active
  294. static boolean        st_statusbaron;
  295.  
  296. // whether status bar chat is active
  297. static boolean        st_chat;
  298.  
  299. // value of st_chat before message popped up
  300. static boolean        st_oldchat;
  301.  
  302. // whether chat window has the cursor on
  303. static boolean        st_cursoron;
  304.  
  305. // !deathmatch
  306. static boolean        st_notdeathmatch; 
  307.  
  308. // !deathmatch && st_statusbaron
  309. static boolean        st_armson;
  310.  
  311. // !deathmatch
  312. static boolean        st_fragson; 
  313.  
  314. // main bar left
  315. static patch_t*        sbar;
  316.  
  317. // 0-9, tall numbers
  318. static patch_t*        tallnum[10];
  319.  
  320. // tall % sign
  321. static patch_t*        tallpercent;
  322.  
  323. // 0-9, short, yellow (,different!) numbers
  324. static patch_t*        shortnum[10];
  325.  
  326. // 3 key-cards, 3 skulls
  327. static patch_t*        keys[NUMCARDS]; 
  328.  
  329. // face status patches
  330. static patch_t*        faces[ST_NUMFACES];
  331.  
  332. // face background
  333. static patch_t*        faceback;
  334.  
  335.  // main bar right
  336. static patch_t*        armsbg;
  337.  
  338. // weapon ownership patches
  339. static patch_t*        arms[6][2]; 
  340.  
  341. // ready-weapon widget
  342. static st_number_t    w_ready;
  343.  
  344.  // in deathmatch only, summary of frags stats
  345. static st_number_t    w_frags;
  346.  
  347. // health widget
  348. static st_percent_t    w_health;
  349.  
  350. // arms background
  351. static st_binicon_t    w_armsbg; 
  352.  
  353.  
  354. // weapon ownership widgets
  355. static st_multicon_t    w_arms[6];
  356.  
  357. // face status widget
  358. static st_multicon_t    w_faces; 
  359.  
  360. // keycard widgets
  361. static st_multicon_t    w_keyboxes[3];
  362.  
  363. // armor widget
  364. static st_percent_t    w_armor;
  365.  
  366. // ammo widgets
  367. static st_number_t    w_ammo[4];
  368.  
  369. // max ammo widgets
  370. static st_number_t    w_maxammo[4]; 
  371.  
  372.  
  373.  
  374.  // number of frags so far in deathmatch
  375. static int    st_fragscount;
  376.  
  377. // used to use appopriately pained face
  378. static int    st_oldhealth = -1;
  379.  
  380. // used for evil grin
  381. static boolean    oldweaponsowned[NUMWEAPONS]; 
  382.  
  383.  // count until face changes
  384. static int    st_facecount = 0;
  385.  
  386. // current face index, used by w_faces
  387. static int    st_faceindex = 0;
  388.  
  389. // holds key-type for each key box on bar
  390. static int    keyboxes[3]; 
  391.  
  392. // a random number per tick
  393. static int    st_randomnumber;  
  394.  
  395.  
  396.  
  397. // Massive bunches of cheat shit
  398. //  to keep it from being easy to figure them out.
  399. // Yeah, right...
  400. unsigned char    cheat_mus_seq[] =
  401. {
  402.     0xb2, 0x26, 0xb6, 0xae, 0xea, 1, 0, 0, 0xff
  403. };
  404.  
  405. unsigned char    cheat_choppers_seq[] =
  406. {
  407.     0xb2, 0x26, 0xe2, 0x32, 0xf6, 0x2a, 0x2a, 0xa6, 0x6a, 0xea, 0xff // id...
  408. };
  409.  
  410. unsigned char    cheat_god_seq[] =
  411. {
  412.     0xb2, 0x26, 0x26, 0xaa, 0x26, 0xff  // iddqd
  413. };
  414.  
  415. unsigned char    cheat_ammo_seq[] =
  416. {
  417.     0xb2, 0x26, 0xf2, 0x66, 0xa2, 0xff    // idkfa
  418. };
  419.  
  420. unsigned char    cheat_ammonokey_seq[] =
  421. {
  422.     0xb2, 0x26, 0x66, 0xa2, 0xff    // idfa
  423. };
  424.  
  425.  
  426. // Smashing Pumpkins Into Samml Piles Of Putried Debris. 
  427. unsigned char    cheat_noclip_seq[] =
  428. {
  429.     0xb2, 0x26, 0xea, 0x2a, 0xb2,    // idspispopd
  430.     0xea, 0x2a, 0xf6, 0x2a, 0x26, 0xff
  431. };
  432.  
  433. //
  434. unsigned char    cheat_commercial_noclip_seq[] =
  435. {
  436.     0xb2, 0x26, 0xe2, 0x36, 0xb2, 0x2a, 0xff    // idclip
  437. }; 
  438.  
  439.  
  440.  
  441. unsigned char    cheat_powerup_seq[7][10] =
  442. {
  443.     { 0xb2, 0x26, 0x62, 0xa6, 0x32, 0xf6, 0x36, 0x26, 0x6e, 0xff },     // beholdv
  444.     { 0xb2, 0x26, 0x62, 0xa6, 0x32, 0xf6, 0x36, 0x26, 0xea, 0xff },     // beholds
  445.     { 0xb2, 0x26, 0x62, 0xa6, 0x32, 0xf6, 0x36, 0x26, 0xb2, 0xff },     // beholdi
  446.     { 0xb2, 0x26, 0x62, 0xa6, 0x32, 0xf6, 0x36, 0x26, 0x6a, 0xff },     // beholdr
  447.     { 0xb2, 0x26, 0x62, 0xa6, 0x32, 0xf6, 0x36, 0x26, 0xa2, 0xff },     // beholda
  448.     { 0xb2, 0x26, 0x62, 0xa6, 0x32, 0xf6, 0x36, 0x26, 0x36, 0xff },     // beholdl
  449.     { 0xb2, 0x26, 0x62, 0xa6, 0x32, 0xf6, 0x36, 0x26, 0xff }        // behold
  450. };
  451.  
  452.  
  453. unsigned char    cheat_clev_seq[] =
  454. {
  455.     0xb2, 0x26,  0xe2, 0x36, 0xa6, 0x6e, 1, 0, 0, 0xff    // idclev
  456. };
  457.  
  458.  
  459. // my position cheat
  460. unsigned char    cheat_mypos_seq[] =
  461. {
  462.     0xb2, 0x26, 0xb6, 0xba, 0x2a, 0xf6, 0xea, 0xff    // idmypos
  463. }; 
  464.  
  465.  
  466. // Now what?
  467. cheatseq_t    cheat_mus = { cheat_mus_seq, 0 };
  468. cheatseq_t    cheat_god = { cheat_god_seq, 0 };
  469. cheatseq_t    cheat_ammo = { cheat_ammo_seq, 0 };
  470. cheatseq_t    cheat_ammonokey = { cheat_ammonokey_seq, 0 };
  471. cheatseq_t    cheat_noclip = { cheat_noclip_seq, 0 };
  472. cheatseq_t    cheat_commercial_noclip = { cheat_commercial_noclip_seq, 0 };
  473.  
  474. cheatseq_t    cheat_powerup[7] =
  475. {
  476.     { cheat_powerup_seq[0], 0 },
  477.     { cheat_powerup_seq[1], 0 },
  478.     { cheat_powerup_seq[2], 0 },
  479.     { cheat_powerup_seq[3], 0 },
  480.     { cheat_powerup_seq[4], 0 },
  481.     { cheat_powerup_seq[5], 0 },
  482.     { cheat_powerup_seq[6], 0 }
  483. };
  484.  
  485. cheatseq_t    cheat_choppers = { cheat_choppers_seq, 0 };
  486. cheatseq_t    cheat_clev = { cheat_clev_seq, 0 };
  487. cheatseq_t    cheat_mypos = { cheat_mypos_seq, 0 };
  488.  
  489.  
  490. // 
  491. extern char*    mapnames[];
  492.  
  493.  
  494. //
  495. // STATUS BAR CODE
  496. //
  497. void ST_Stop(void);
  498.  
  499. void ST_refreshBackground(void)
  500. {
  501.  
  502.     if (st_statusbaron)
  503.     {
  504.     V_DrawPatch(ST_X, 0, BG, sbar);
  505.  
  506.     if (netgame)
  507.         V_DrawPatch(ST_FX, 0, BG, faceback);
  508.  
  509.     V_CopyRect(ST_X, 0, BG, ST_WIDTH, ST_HEIGHT, ST_X, ST_Y, FG);
  510.     }
  511.  
  512. }
  513.  
  514.  
  515. // Respond to keyboard input events,
  516. //  intercept cheats.
  517. boolean
  518. ST_Responder (event_t* ev)
  519. {
  520.   int        i;
  521.     
  522.   // Filter automap on/off.
  523.   if (ev->type == ev_keyup
  524.       && ((ev->data1 & 0xffff0000) == AM_MSGHEADER))
  525.   {
  526.     switch(ev->data1)
  527.     {
  528.       case AM_MSGENTERED:
  529.     st_gamestate = AutomapState;
  530.     st_firsttime = true;
  531.     break;
  532.     
  533.       case AM_MSGEXITED:
  534.     //    fprintf(stderr, "AM exited\n");
  535.     st_gamestate = FirstPersonState;
  536.     break;
  537.     }
  538.   }
  539.  
  540.   // if a user keypress...
  541.   else if (ev->type == ev_keydown)
  542.   {
  543.     if (!netgame)
  544.     {
  545.       // b. - enabled for more debug fun.
  546.       // if (gameskill != sk_nightmare) {
  547.       
  548.       // 'dqd' cheat for toggleable god mode
  549.       if (cht_CheckCheat(&cheat_god, ev->data1))
  550.       {
  551.     plyr->cheats ^= CF_GODMODE;
  552.     if (plyr->cheats & CF_GODMODE)
  553.     {
  554.       if (plyr->mo)
  555.         plyr->mo->health = 100;
  556.       
  557.       plyr->health = 100;
  558.       plyr->message = STSTR_DQDON;
  559.     }
  560.     else 
  561.       plyr->message = STSTR_DQDOFF;
  562.       }
  563.       // 'fa' cheat for killer fucking arsenal
  564.       else if (cht_CheckCheat(&cheat_ammonokey, ev->data1))
  565.       {
  566.     plyr->armorpoints = 200;
  567.     plyr->armortype = 2;
  568.     
  569.     for (i=0;i<NUMWEAPONS;i++)
  570.       plyr->weaponowned[i] = true;
  571.     
  572.     for (i=0;i<NUMAMMO;i++)
  573.       plyr->ammo[i] = plyr->maxammo[i];
  574.     
  575.     plyr->message = STSTR_FAADDED;
  576.       }
  577.       // 'kfa' cheat for key full ammo
  578.       else if (cht_CheckCheat(&cheat_ammo, ev->data1))
  579.       {
  580.     plyr->armorpoints = 200;
  581.     plyr->armortype = 2;
  582.     
  583.     for (i=0;i<NUMWEAPONS;i++)
  584.       plyr->weaponowned[i] = true;
  585.     
  586.     for (i=0;i<NUMAMMO;i++)
  587.       plyr->ammo[i] = plyr->maxammo[i];
  588.     
  589.     for (i=0;i<NUMCARDS;i++)
  590.       plyr->cards[i] = true;
  591.     
  592.     plyr->message = STSTR_KFAADDED;
  593.       }
  594.       // 'mus' cheat for changing music
  595.       else if (cht_CheckCheat(&cheat_mus, ev->data1))
  596.       {
  597.     
  598.     char    buf[3];
  599.     int        musnum;
  600.     
  601.     plyr->message = STSTR_MUS;
  602.     cht_GetParam(&cheat_mus, buf);
  603.     
  604.     if (gamemode == commercial)
  605.     {
  606.       musnum = mus_runnin + (buf[0]-'0')*10 + buf[1]-'0' - 1;
  607.       
  608.       if (((buf[0]-'0')*10 + buf[1]-'0') > 35)
  609.         plyr->message = STSTR_NOMUS;
  610.       else
  611.         S_ChangeMusic(musnum, 1);
  612.     }
  613.     else
  614.     {
  615.       musnum = mus_e1m1 + (buf[0]-'1')*9 + (buf[1]-'1');
  616.       
  617.       if (((buf[0]-'1')*9 + buf[1]-'1') > 31)
  618.         plyr->message = STSTR_NOMUS;
  619.       else
  620.         S_ChangeMusic(musnum, 1);
  621.     }
  622.       }
  623.       // Simplified, accepting both "noclip" and "idspispopd".
  624.       // no clipping mode cheat
  625.       else if ( cht_CheckCheat(&cheat_noclip, ev->data1) 
  626.         || cht_CheckCheat(&cheat_commercial_noclip,ev->data1) )
  627.       {    
  628.     plyr->cheats ^= CF_NOCLIP;
  629.     
  630.     if (plyr->cheats & CF_NOCLIP)
  631.       plyr->message = STSTR_NCON;
  632.     else
  633.       plyr->message = STSTR_NCOFF;
  634.       }
  635.       // 'behold?' power-up cheats
  636.       for (i=0;i<6;i++)
  637.       {
  638.     if (cht_CheckCheat(&cheat_powerup[i], ev->data1))
  639.     {
  640.       if (!plyr->powers[i])
  641.         P_GivePower( plyr, i);
  642.       else if (i!=pw_strength)
  643.         plyr->powers[i] = 1;
  644.       else
  645.         plyr->powers[i] = 0;
  646.       
  647.       plyr->message = STSTR_BEHOLDX;
  648.     }
  649.       }
  650.       
  651.       // 'behold' power-up menu
  652.       if (cht_CheckCheat(&cheat_powerup[6], ev->data1))
  653.       {
  654.     plyr->message = STSTR_BEHOLD;
  655.       }
  656.       // 'choppers' invulnerability & chainsaw
  657.       else if (cht_CheckCheat(&cheat_choppers, ev->data1))
  658.       {
  659.     plyr->weaponowned[wp_chainsaw] = true;
  660.     plyr->powers[pw_invulnerability] = true;
  661.     plyr->message = STSTR_CHOPPERS;
  662.       }
  663.       // 'mypos' for player position
  664.       else if (cht_CheckCheat(&cheat_mypos, ev->data1))
  665.       {
  666.     static char    buf[ST_MSGWIDTH];
  667.     sprintf(buf, "ang=0x%x;x,y=(0x%x,0x%x)",
  668.         players[consoleplayer].mo->angle,
  669.         players[consoleplayer].mo->x,
  670.         players[consoleplayer].mo->y);
  671.     plyr->message = buf;
  672.       }
  673.     }
  674.     
  675.     // 'clev' change-level cheat
  676.     if (cht_CheckCheat(&cheat_clev, ev->data1))
  677.     {
  678.       char        buf[3];
  679.       int        epsd;
  680.       int        map;
  681.       
  682.       cht_GetParam(&cheat_clev, buf);
  683.       
  684.       if (gamemode == commercial)
  685.       {
  686.     epsd = 0;
  687.     map = (buf[0] - '0')*10 + buf[1] - '0';
  688.       }
  689.       else
  690.       {
  691.     epsd = buf[0] - '0';
  692.     map = buf[1] - '0';
  693.       }
  694.  
  695.       // Catch invalid maps.
  696.       if (epsd < 1)
  697.     return false;
  698.  
  699.       if (map < 1)
  700.     return false;
  701.       
  702.       // Ohmygod - this is not going to work.
  703.       if ((gamemode == retail)
  704.       && ((epsd > 4) || (map > 9)))
  705.     return false;
  706.  
  707.       if ((gamemode == registered)
  708.       && ((epsd > 3) || (map > 9)))
  709.     return false;
  710.  
  711.       if ((gamemode == shareware)
  712.       && ((epsd > 1) || (map > 9)))
  713.     return false;
  714.  
  715.       if ((gamemode == commercial)
  716.     && (( epsd > 1) || (map > 34)))
  717.     return false;
  718.  
  719.       // So be it.
  720.       plyr->message = STSTR_CLEV;
  721.       G_DeferedInitNew(gameskill, epsd, map);
  722.     }    
  723.   }
  724.   return false;
  725. }
  726.  
  727.  
  728.  
  729. int ST_calcPainOffset(void)
  730. {
  731.     int        health;
  732.     static int    lastcalc;
  733.     static int    oldhealth = -1;
  734.     
  735.     health = plyr->health > 100 ? 100 : plyr->health;
  736.  
  737.     if (health != oldhealth)
  738.     {
  739.     lastcalc = ST_FACESTRIDE * (((100 - health) * ST_NUMPAINFACES) / 101);
  740.     oldhealth = health;
  741.     }
  742.     return lastcalc;
  743. }
  744.  
  745.  
  746. //
  747. // This is a not-very-pretty routine which handles
  748. //  the face states and their timing.
  749. // the precedence of expressions is:
  750. //  dead > evil grin > turned head > straight ahead
  751. //
  752. void ST_updateFaceWidget(void)
  753. {
  754.     int        i;
  755.     angle_t    badguyangle;
  756.     angle_t    diffang;
  757.     static int    lastattackdown = -1;
  758.     static int    priority = 0;
  759.     boolean    doevilgrin;
  760.  
  761.     if (priority < 10)
  762.     {
  763.     // dead
  764.     if (!plyr->health)
  765.     {
  766.         priority = 9;
  767.         st_faceindex = ST_DEADFACE;
  768.         st_facecount = 1;
  769.     }
  770.     }
  771.  
  772.     if (priority < 9)
  773.     {
  774.     if (plyr->bonuscount)
  775.     {
  776.         // picking up bonus
  777.         doevilgrin = false;
  778.  
  779.         for (i=0;i<NUMWEAPONS;i++)
  780.         {
  781.         if (oldweaponsowned[i] != plyr->weaponowned[i])
  782.         {
  783.             doevilgrin = true;
  784.             oldweaponsowned[i] = plyr->weaponowned[i];
  785.         }
  786.         }
  787.         if (doevilgrin) 
  788.         {
  789.         // evil grin if just picked up weapon
  790.         priority = 8;
  791.         st_facecount = ST_EVILGRINCOUNT;
  792.         st_faceindex = ST_calcPainOffset() + ST_EVILGRINOFFSET;
  793.         }
  794.     }
  795.  
  796.     }
  797.   
  798.     if (priority < 8)
  799.     {
  800.     if (plyr->damagecount
  801.         && plyr->attacker
  802.         && plyr->attacker != plyr->mo)
  803.     {
  804.         // being attacked
  805.         priority = 7;
  806.         
  807.         if (plyr->health - st_oldhealth > ST_MUCHPAIN)
  808.         {
  809.         st_facecount = ST_TURNCOUNT;
  810.         st_faceindex = ST_calcPainOffset() + ST_OUCHOFFSET;
  811.         }
  812.         else
  813.         {
  814.         badguyangle = R_PointToAngle2(plyr->mo->x,
  815.                           plyr->mo->y,
  816.                           plyr->attacker->x,
  817.                           plyr->attacker->y);
  818.         
  819.         if (badguyangle > plyr->mo->angle)
  820.         {
  821.             // whether right or left
  822.             diffang = badguyangle - plyr->mo->angle;
  823.             i = diffang > ANG180; 
  824.         }
  825.         else
  826.         {
  827.             // whether left or right
  828.             diffang = plyr->mo->angle - badguyangle;
  829.             i = diffang <= ANG180; 
  830.         } // confusing, aint it?
  831.  
  832.         
  833.         st_facecount = ST_TURNCOUNT;
  834.         st_faceindex = ST_calcPainOffset();
  835.         
  836.         if (diffang < ANG45)
  837.         {
  838.             // head-on    
  839.             st_faceindex += ST_RAMPAGEOFFSET;
  840.         }
  841.         else if (i)
  842.         {
  843.             // turn face right
  844.             st_faceindex += ST_TURNOFFSET;
  845.         }
  846.         else
  847.         {
  848.             // turn face left
  849.             st_faceindex += ST_TURNOFFSET+1;
  850.         }
  851.         }
  852.     }
  853.     }
  854.   
  855.     if (priority < 7)
  856.     {
  857.     // getting hurt because of your own damn stupidity
  858.     if (plyr->damagecount)
  859.     {
  860.         if (plyr->health - st_oldhealth > ST_MUCHPAIN)
  861.         {
  862.         priority = 7;
  863.         st_facecount = ST_TURNCOUNT;
  864.         st_faceindex = ST_calcPainOffset() + ST_OUCHOFFSET;
  865.         }
  866.         else
  867.         {
  868.         priority = 6;
  869.         st_facecount = ST_TURNCOUNT;
  870.         st_faceindex = ST_calcPainOffset() + ST_RAMPAGEOFFSET;
  871.         }
  872.  
  873.     }
  874.  
  875.     }
  876.   
  877.     if (priority < 6)
  878.     {
  879.     // rapid firing
  880.     if (plyr->attackdown)
  881.     {
  882.         if (lastattackdown==-1)
  883.         lastattackdown = ST_RAMPAGEDELAY;
  884.         else if (!--lastattackdown)
  885.         {
  886.         priority = 5;
  887.         st_faceindex = ST_calcPainOffset() + ST_RAMPAGEOFFSET;
  888.         st_facecount = 1;
  889.         lastattackdown = 1;
  890.         }
  891.     }
  892.     else
  893.         lastattackdown = -1;
  894.  
  895.     }
  896.   
  897.     if (priority < 5)
  898.     {
  899.     // invulnerability
  900.     if ((plyr->cheats & CF_GODMODE)
  901.         || plyr->powers[pw_invulnerability])
  902.     {
  903.         priority = 4;
  904.  
  905.         st_faceindex = ST_GODFACE;
  906.         st_facecount = 1;
  907.  
  908.     }
  909.  
  910.     }
  911.  
  912.     // look left or look right if the facecount has timed out
  913.     if (!st_facecount)
  914.     {
  915.     st_faceindex = ST_calcPainOffset() + (st_randomnumber % 3);
  916.     st_facecount = ST_STRAIGHTFACECOUNT;
  917.     priority = 0;
  918.     }
  919.  
  920.     st_facecount--;
  921.  
  922. }
  923.  
  924. void ST_updateWidgets(void)
  925. {
  926.     static int    largeammo = 1994; // means "n/a"
  927.     int        i;
  928.  
  929.     // must redirect the pointer if the ready weapon has changed.
  930.     //  if (w_ready.data != plyr->readyweapon)
  931.     //  {
  932.     if (weaponinfo[plyr->readyweapon].ammo == am_noammo)
  933.     w_ready.num = &largeammo;
  934.     else
  935.     w_ready.num = &plyr->ammo[weaponinfo[plyr->readyweapon].ammo];
  936.     //{
  937.     // static int tic=0;
  938.     // static int dir=-1;
  939.     // if (!(tic&15))
  940.     //   plyr->ammo[weaponinfo[plyr->readyweapon].ammo]+=dir;
  941.     // if (plyr->ammo[weaponinfo[plyr->readyweapon].ammo] == -100)
  942.     //   dir = 1;
  943.     // tic++;
  944.     // }
  945.     w_ready.data = plyr->readyweapon;
  946.  
  947.     // if (*w_ready.on)
  948.     //  STlib_updateNum(&w_ready, true);
  949.     // refresh weapon change
  950.     //  }
  951.  
  952.     // update keycard multiple widgets
  953.     for (i=0;i<3;i++)
  954.     {
  955.     keyboxes[i] = plyr->cards[i] ? i : -1;
  956.  
  957.     if (plyr->cards[i+3])
  958.         keyboxes[i] = i+3;
  959.     }
  960.  
  961.     // refresh everything if this is him coming back to life
  962.     ST_updateFaceWidget();
  963.  
  964.     // used by the w_armsbg widget
  965.     st_notdeathmatch = !deathmatch;
  966.     
  967.     // used by w_arms[] widgets
  968.     st_armson = st_statusbaron && !deathmatch; 
  969.  
  970.     // used by w_frags widget
  971.     st_fragson = deathmatch && st_statusbaron; 
  972.     st_fragscount = 0;
  973.  
  974.     for (i=0 ; i<MAXPLAYERS ; i++)
  975.     {
  976.     if (i != consoleplayer)
  977.         st_fragscount += plyr->frags[i];
  978.     else
  979.         st_fragscount -= plyr->frags[i];
  980.     }
  981.  
  982.     // get rid of chat window if up because of message
  983.     if (!--st_msgcounter)
  984.     st_chat = st_oldchat;
  985.  
  986. }
  987.  
  988. void ST_Ticker (void)
  989. {
  990.  
  991.     st_clock++;
  992.     st_randomnumber = M_Random();
  993.     ST_updateWidgets();
  994.     st_oldhealth = plyr->health;
  995.  
  996. }
  997.  
  998. static int st_palette = 0;
  999.  
  1000. void ST_doPaletteStuff(void)
  1001. {
  1002.  
  1003.     int        palette;
  1004.     byte*    pal;
  1005.     int        cnt;
  1006.     int        bzc;
  1007.  
  1008.     cnt = plyr->damagecount;
  1009.  
  1010.     if (plyr->powers[pw_strength])
  1011.     {
  1012.     // slowly fade the berzerk out
  1013.       bzc = 12 - (plyr->powers[pw_strength]>>6);
  1014.  
  1015.     if (bzc > cnt)
  1016.         cnt = bzc;
  1017.     }
  1018.     
  1019.     if (cnt)
  1020.     {
  1021.     palette = (cnt+7)>>3;
  1022.     
  1023.     if (palette >= NUMREDPALS)
  1024.         palette = NUMREDPALS-1;
  1025.  
  1026.     palette += STARTREDPALS;
  1027.     }
  1028.  
  1029.     else if (plyr->bonuscount)
  1030.     {
  1031.     palette = (plyr->bonuscount+7)>>3;
  1032.  
  1033.     if (palette >= NUMBONUSPALS)
  1034.         palette = NUMBONUSPALS-1;
  1035.  
  1036.     palette += STARTBONUSPALS;
  1037.     }
  1038.  
  1039.     else if ( plyr->powers[pw_ironfeet] > 4*32
  1040.           || plyr->powers[pw_ironfeet]&8)
  1041.     palette = RADIATIONPAL;
  1042.     else
  1043.     palette = 0;
  1044.  
  1045.     if (palette != st_palette)
  1046.     {
  1047.     st_palette = palette;
  1048.     pal = (byte *) W_CacheLumpNum (lu_palette, PU_CACHE)+palette*768;
  1049.     I_SetPalette (pal);
  1050.     }
  1051.  
  1052. }
  1053.  
  1054. void ST_drawWidgets(boolean refresh)
  1055. {
  1056.     int        i;
  1057.  
  1058.     // used by w_arms[] widgets
  1059.     st_armson = st_statusbaron && !deathmatch;
  1060.  
  1061.     // used by w_frags widget
  1062.     st_fragson = deathmatch && st_statusbaron; 
  1063.  
  1064.     STlib_updateNum(&w_ready, refresh);
  1065.  
  1066.     for (i=0;i<4;i++)
  1067.     {
  1068.     STlib_updateNum(&w_ammo[i], refresh);
  1069.     STlib_updateNum(&w_maxammo[i], refresh);
  1070.     }
  1071.  
  1072.     STlib_updatePercent(&w_health, refresh);
  1073.     STlib_updatePercent(&w_armor, refresh);
  1074.  
  1075.     STlib_updateBinIcon(&w_armsbg, refresh);
  1076.  
  1077.     for (i=0;i<6;i++)
  1078.     STlib_updateMultIcon(&w_arms[i], refresh);
  1079.  
  1080.     STlib_updateMultIcon(&w_faces, refresh);
  1081.  
  1082.     for (i=0;i<3;i++)
  1083.     STlib_updateMultIcon(&w_keyboxes[i], refresh);
  1084.  
  1085.     STlib_updateNum(&w_frags, refresh);
  1086.  
  1087. }
  1088.  
  1089. void ST_doRefresh(void)
  1090. {
  1091.  
  1092.     st_firsttime = false;
  1093.  
  1094.     // draw status bar background to off-screen buff
  1095.     ST_refreshBackground();
  1096.  
  1097.     // and refresh all widgets
  1098.     ST_drawWidgets(true);
  1099.  
  1100. }
  1101.  
  1102. void ST_diffDraw(void)
  1103. {
  1104.     // update all widgets
  1105.     ST_drawWidgets(false);
  1106. }
  1107.  
  1108. void ST_Drawer (boolean fullscreen, boolean refresh)
  1109. {
  1110.   
  1111.     st_statusbaron = (!fullscreen) || automapactive;
  1112.     st_firsttime = st_firsttime || refresh;
  1113.  
  1114.     // Do red-/gold-shifts from damage/items
  1115.     ST_doPaletteStuff();
  1116.  
  1117.     // If just after ST_Start(), refresh all
  1118.     if (st_firsttime) ST_doRefresh();
  1119.     // Otherwise, update as little as possible
  1120.     else ST_diffDraw();
  1121.  
  1122. }
  1123.  
  1124. void ST_loadGraphics(void)
  1125. {
  1126.  
  1127.     int        i;
  1128.     int        j;
  1129.     int        facenum;
  1130.     
  1131.     char    namebuf[9];
  1132.  
  1133.     // Load the numbers, tall and short
  1134.     for (i=0;i<10;i++)
  1135.     {
  1136.     sprintf(namebuf, "STTNUM%d", i);
  1137.     tallnum[i] = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
  1138.  
  1139.     sprintf(namebuf, "STYSNUM%d", i);
  1140.     shortnum[i] = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
  1141.     }
  1142.  
  1143.     // Load percent key.
  1144.     //Note: why not load STMINUS here, too?
  1145.     tallpercent = (patch_t *) W_CacheLumpName("STTPRCNT", PU_STATIC);
  1146.  
  1147.     // key cards
  1148.     for (i=0;i<NUMCARDS;i++)
  1149.     {
  1150.     sprintf(namebuf, "STKEYS%d", i);
  1151.     keys[i] = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
  1152.     }
  1153.  
  1154.     // arms background
  1155.     armsbg = (patch_t *) W_CacheLumpName("STARMS", PU_STATIC);
  1156.  
  1157.     // arms ownership widgets
  1158.     for (i=0;i<6;i++)
  1159.     {
  1160.     sprintf(namebuf, "STGNUM%d", i+2);
  1161.  
  1162.     // gray #
  1163.     arms[i][0] = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
  1164.  
  1165.     // yellow #
  1166.     arms[i][1] = shortnum[i+2]; 
  1167.     }
  1168.  
  1169.     // face backgrounds for different color players
  1170.     sprintf(namebuf, "STFB%d", consoleplayer);
  1171.     faceback = (patch_t *) W_CacheLumpName(namebuf, PU_STATIC);
  1172.  
  1173.     // status bar background bits
  1174.     sbar = (patch_t *) W_CacheLumpName("STBAR", PU_STATIC);
  1175.  
  1176.     // face states
  1177.     facenum = 0;
  1178.     for (i=0;i<ST_NUMPAINFACES;i++)
  1179.     {
  1180.     for (j=0;j<ST_NUMSTRAIGHTFACES;j++)
  1181.     {
  1182.         sprintf(namebuf, "STFST%d%d", i, j);
  1183.         faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
  1184.     }
  1185.     sprintf(namebuf, "STFTR%d0", i);    // turn right
  1186.     faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
  1187.     sprintf(namebuf, "STFTL%d0", i);    // turn left
  1188.     faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
  1189.     sprintf(namebuf, "STFOUCH%d", i);    // ouch!
  1190.     faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
  1191.     sprintf(namebuf, "STFEVL%d", i);    // evil grin ;)
  1192.     faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
  1193.     sprintf(namebuf, "STFKILL%d", i);    // pissed off
  1194.     faces[facenum++] = W_CacheLumpName(namebuf, PU_STATIC);
  1195.     }
  1196.     faces[facenum++] = W_CacheLumpName("STFGOD0", PU_STATIC);
  1197.     faces[facenum++] = W_CacheLumpName("STFDEAD0", PU_STATIC);
  1198.  
  1199. }
  1200.  
  1201. void ST_loadData(void)
  1202. {
  1203.     lu_palette = W_GetNumForName ("PLAYPAL");
  1204.     ST_loadGraphics();
  1205. }
  1206.  
  1207. void ST_unloadGraphics(void)
  1208. {
  1209.  
  1210.     int i;
  1211.  
  1212.     // unload the numbers, tall and short
  1213.     for (i=0;i<10;i++)
  1214.     {
  1215.     Z_ChangeTag(tallnum[i], PU_CACHE);
  1216.     Z_ChangeTag(shortnum[i], PU_CACHE);
  1217.     }
  1218.     // unload tall percent
  1219.     Z_ChangeTag(tallpercent, PU_CACHE); 
  1220.  
  1221.     // unload arms background
  1222.     Z_ChangeTag(armsbg, PU_CACHE); 
  1223.  
  1224.     // unload gray #'s
  1225.     for (i=0;i<6;i++)
  1226.     Z_ChangeTag(arms[i][0], PU_CACHE);
  1227.     
  1228.     // unload the key cards
  1229.     for (i=0;i<NUMCARDS;i++)
  1230.     Z_ChangeTag(keys[i], PU_CACHE);
  1231.  
  1232.     Z_ChangeTag(sbar, PU_CACHE);
  1233.     Z_ChangeTag(faceback, PU_CACHE);
  1234.  
  1235.     for (i=0;i<ST_NUMFACES;i++)
  1236.     Z_ChangeTag(faces[i], PU_CACHE);
  1237.  
  1238.     // Note: nobody ain't seen no unloading
  1239.     //   of stminus yet. Dude.
  1240.     
  1241.  
  1242. }
  1243.  
  1244. void ST_unloadData(void)
  1245. {
  1246.     ST_unloadGraphics();
  1247. }
  1248.  
  1249. void ST_initData(void)
  1250. {
  1251.  
  1252.     int        i;
  1253.  
  1254.     st_firsttime = true;
  1255.     plyr = &players[consoleplayer];
  1256.  
  1257.     st_clock = 0;
  1258.     st_chatstate = StartChatState;
  1259.     st_gamestate = FirstPersonState;
  1260.  
  1261.     st_statusbaron = true;
  1262.     st_oldchat = st_chat = false;
  1263.     st_cursoron = false;
  1264.  
  1265.     st_faceindex = 0;
  1266.     st_palette = -1;
  1267.  
  1268.     st_oldhealth = -1;
  1269.  
  1270.     for (i=0;i<NUMWEAPONS;i++)
  1271.     oldweaponsowned[i] = plyr->weaponowned[i];
  1272.  
  1273.     for (i=0;i<3;i++)
  1274.     keyboxes[i] = -1;
  1275.  
  1276.     STlib_init();
  1277.  
  1278. }
  1279.  
  1280.  
  1281.  
  1282. void ST_createWidgets(void)
  1283. {
  1284.  
  1285.     int i;
  1286.  
  1287.     // ready weapon ammo
  1288.     STlib_initNum(&w_ready,
  1289.           ST_AMMOX,
  1290.           ST_AMMOY,
  1291.           tallnum,
  1292.           &plyr->ammo[weaponinfo[plyr->readyweapon].ammo],
  1293.           &st_statusbaron,
  1294.           ST_AMMOWIDTH );
  1295.  
  1296.     // the last weapon type
  1297.     w_ready.data = plyr->readyweapon; 
  1298.  
  1299.     // health percentage
  1300.     STlib_initPercent(&w_health,
  1301.               ST_HEALTHX,
  1302.               ST_HEALTHY,
  1303.               tallnum,
  1304.               &plyr->health,
  1305.               &st_statusbaron,
  1306.               tallpercent);
  1307.  
  1308.     // arms background
  1309.     STlib_initBinIcon(&w_armsbg,
  1310.               ST_ARMSBGX,
  1311.               ST_ARMSBGY,
  1312.               armsbg,
  1313.               &st_notdeathmatch,
  1314.               &st_statusbaron);
  1315.  
  1316.     // weapons owned
  1317.     for(i=0;i<6;i++)
  1318.     {
  1319.     STlib_initMultIcon(&w_arms[i],
  1320.                ST_ARMSX+(i%3)*ST_ARMSXSPACE,
  1321.                ST_ARMSY+(i/3)*ST_ARMSYSPACE,
  1322.                arms[i], (int *) &plyr->weaponowned[i+1],
  1323.                &st_armson);
  1324.     }
  1325.  
  1326.     // frags sum
  1327.     STlib_initNum(&w_frags,
  1328.           ST_FRAGSX,
  1329.           ST_FRAGSY,
  1330.           tallnum,
  1331.           &st_fragscount,
  1332.           &st_fragson,
  1333.           ST_FRAGSWIDTH);
  1334.  
  1335.     // faces
  1336.     STlib_initMultIcon(&w_faces,
  1337.                ST_FACESX,
  1338.                ST_FACESY,
  1339.                faces,
  1340.                &st_faceindex,
  1341.                &st_statusbaron);
  1342.  
  1343.     // armor percentage - should be colored later
  1344.     STlib_initPercent(&w_armor,
  1345.               ST_ARMORX,
  1346.               ST_ARMORY,
  1347.               tallnum,
  1348.               &plyr->armorpoints,
  1349.               &st_statusbaron, tallpercent);
  1350.  
  1351.     // keyboxes 0-2
  1352.     STlib_initMultIcon(&w_keyboxes[0],
  1353.                ST_KEY0X,
  1354.                ST_KEY0Y,
  1355.                keys,
  1356.                &keyboxes[0],
  1357.                &st_statusbaron);
  1358.     
  1359.     STlib_initMultIcon(&w_keyboxes[1],
  1360.                ST_KEY1X,
  1361.                ST_KEY1Y,
  1362.                keys,
  1363.                &keyboxes[1],
  1364.                &st_statusbaron);
  1365.  
  1366.     STlib_initMultIcon(&w_keyboxes[2],
  1367.                ST_KEY2X,
  1368.                ST_KEY2Y,
  1369.                keys,
  1370.                &keyboxes[2],
  1371.                &st_statusbaron);
  1372.  
  1373.     // ammo count (all four kinds)
  1374.     STlib_initNum(&w_ammo[0],
  1375.           ST_AMMO0X,
  1376.           ST_AMMO0Y,
  1377.           shortnum,
  1378.           &plyr->ammo[0],
  1379.           &st_statusbaron,
  1380.           ST_AMMO0WIDTH);
  1381.  
  1382.     STlib_initNum(&w_ammo[1],
  1383.           ST_AMMO1X,
  1384.           ST_AMMO1Y,
  1385.           shortnum,
  1386.           &plyr->ammo[1],
  1387.           &st_statusbaron,
  1388.           ST_AMMO1WIDTH);
  1389.  
  1390.     STlib_initNum(&w_ammo[2],
  1391.           ST_AMMO2X,
  1392.           ST_AMMO2Y,
  1393.           shortnum,
  1394.           &plyr->ammo[2],
  1395.           &st_statusbaron,
  1396.           ST_AMMO2WIDTH);
  1397.     
  1398.     STlib_initNum(&w_ammo[3],
  1399.           ST_AMMO3X,
  1400.           ST_AMMO3Y,
  1401.           shortnum,
  1402.           &plyr->ammo[3],
  1403.           &st_statusbaron,
  1404.           ST_AMMO3WIDTH);
  1405.  
  1406.     // max ammo count (all four kinds)
  1407.     STlib_initNum(&w_maxammo[0],
  1408.           ST_MAXAMMO0X,
  1409.           ST_MAXAMMO0Y,
  1410.           shortnum,
  1411.           &plyr->maxammo[0],
  1412.           &st_statusbaron,
  1413.           ST_MAXAMMO0WIDTH);
  1414.  
  1415.     STlib_initNum(&w_maxammo[1],
  1416.           ST_MAXAMMO1X,
  1417.           ST_MAXAMMO1Y,
  1418.           shortnum,
  1419.           &plyr->maxammo[1],
  1420.           &st_statusbaron,
  1421.           ST_MAXAMMO1WIDTH);
  1422.  
  1423.     STlib_initNum(&w_maxammo[2],
  1424.           ST_MAXAMMO2X,
  1425.           ST_MAXAMMO2Y,
  1426.           shortnum,
  1427.           &plyr->maxammo[2],
  1428.           &st_statusbaron,
  1429.           ST_MAXAMMO2WIDTH);
  1430.     
  1431.     STlib_initNum(&w_maxammo[3],
  1432.           ST_MAXAMMO3X,
  1433.           ST_MAXAMMO3Y,
  1434.           shortnum,
  1435.           &plyr->maxammo[3],
  1436.           &st_statusbaron,
  1437.           ST_MAXAMMO3WIDTH);
  1438.  
  1439. }
  1440.  
  1441. static boolean    st_stopped = true;
  1442.  
  1443.  
  1444. void ST_Start (void)
  1445. {
  1446.  
  1447.     if (!st_stopped)
  1448.     ST_Stop();
  1449.  
  1450.     ST_initData();
  1451.     ST_createWidgets();
  1452.     st_stopped = false;
  1453.  
  1454. }
  1455.  
  1456. void ST_Stop (void)
  1457. {
  1458.     if (st_stopped)
  1459.     return;
  1460.  
  1461.     I_SetPalette (W_CacheLumpNum (lu_palette, PU_CACHE));
  1462.  
  1463.     st_stopped = true;
  1464. }
  1465.  
  1466. void ST_Init (void)
  1467. {
  1468.     veryfirsttime = 0;
  1469.     ST_loadData();
  1470.     screens[4] = (byte *) Z_Malloc(ST_WIDTH*ST_HEIGHT, PU_STATIC, 0);
  1471. }
  1472.